/*
 * Copyright© 2003-2019 浙江汇信科技有限公司, All Rights Reserved.
 */
package com.icinfo.cloud.provider.punish.ucase.casemain.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.common.security.util.UserUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.RecordSaveTypeEnum;
import com.icinfo.cloud.provider.common.enums.YesOrNoEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.BaseUtil;
import com.icinfo.cloud.provider.common.utils.HttpUtils;
import com.icinfo.cloud.provider.punish.common.datareport.dto.RevokeDecisionOrCaseInfoDto;
import com.icinfo.cloud.provider.punish.common.datareport.enums.CaseChangeOperationTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataChangeReportRecordService;
import com.icinfo.cloud.provider.punish.common.datareport.service.impl.CaseDataReportDecisionServiceImpl;
import com.icinfo.cloud.provider.punish.common.documentoperate.enums.DocumentTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseAttachmentInfoQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseAttachmentInfoSaveDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CasePartiesRecordQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CasePunishDecisionRevokeRecordDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseStatusEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.DealAfterRevokeTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.CaseAppendixRecordMapper;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.CaseMainInfoMapper;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.CasePunishDecisionRevokeRecordMapper;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseAppendixRecord;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CasePunishDecisionRevokeRecord;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseAttachmentInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CasePartiesInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CasePunishDecisionRevokeRecordVo;
import com.icinfo.cloud.provider.punish.ucase.payment.model.CasePaymentMainRecord;
import com.icinfo.cloud.provider.punish.ucase.payment.service.ICasePaymentMainRecordService;
import com.icinfo.cloud.workflow.config.model.ConfigWorkFlowDetailInfo;
import com.icinfo.cloud.workflow.config.model.ConfigWorkFlowDocument;
import com.icinfo.cloud.workflow.config.service.IConfigWorkFlowDetailInfoService;
import com.icinfo.cloud.workflow.config.service.IConfigWorkFlowDocumentService;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.framework.core.service.support.MyBatisServiceSupport;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 描述: 案件处罚决定撤销记录表 case_punish_decision_revoke_record 对应的Service接口实现类.<br>
 *
 * @author framework generator
 * @date 2022年07月21日
 */
@Service
@Slf4j
public class CasePunishDecisionRevokeRecordServiceImpl extends MyBatisServiceSupport implements ICasePunishDecisionRevokeRecordService {

    @Resource
    private CasePunishDecisionRevokeRecordMapper casePunishDecisionRevokeRecordMapper;
    @Resource
    private CaseMainInfoMapper caseMainInfoMapper;
    @Resource
    private ICaseMainInfoService caseMainInfoService;
    @Resource
    private CaseAppendixRecordMapper caseAppendixRecordMapper;
    @Resource
    private ICasePartiesRecordService casePartiesRecordService;
    @Resource
    private ICaseAppendixRecordService caseAppendixRecordService;
    @Resource
    private ICaseMainInfoStatusChangeRecordService caseMainInfoStatusChangeRecordService;
    @Resource
    private IConfigWorkFlowDocumentService configWorkFlowDocumentService;

    @Resource
    private IConfigWorkFlowDetailInfoService configWorkFlowDetailInfoService;
    @Resource
    private CaseDataReportDecisionServiceImpl caseDataReportDecisionService;
    @Resource
    private ICaseDataChangeReportRecordService caseDataChangeReportRecordService;
    @Resource
    private ICasePaymentMainRecordService casePaymentMainRecordService;
    @Value("${paymentCq.busInvalidUnpayDataUrl}")
    private String busInvalidUnpayDataUrl;



    /**
     * 【V1.3.2】描述：保存案件处罚决定撤销记录基本信息
     *
     * @param saveDto {@link CasePunishDecisionRevokeRecordDto}
     * @return int 保存成功记录数
     * @author xiangyuyu
     * @date 2022/7/22
     * @since 1.3.2
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveCasePunishDecisionRevokeRecordBasicInfo(CasePunishDecisionRevokeRecordDto saveDto) {
        log.info("saveCasePunishDecisionRevokeRecordBasicInfo start...saveDto:{}", saveDto);
        UserDTO userInfo = UserUtil.getUserInfo();
        if (ObjectUtils.isEmpty(userInfo)) {
            throw new BusinessException("登陆失效-saveCasePunishDecisionRevokeRecordBasicInfo");
        }
        String operateType = saveDto.getOperateType();
        if (!RecordSaveTypeEnum.isLegalEnumCode(operateType)) {
            throw new BusinessException("请指定有效的操作类型(1-新增/2-修改)");
        }
        //校验案件信息
        String caseId = saveDto.getCaseId();
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        //校验信息填充完整性
        String errorMsg = validateRevokeBasicInfo(saveDto);
        if (!ObjectUtils.isEmpty(errorMsg)) {
            throw new BusinessException(errorMsg);
        }
        CasePunishDecisionRevokeRecord record = new CasePunishDecisionRevokeRecord();
        BeanUtils.copyProperties(saveDto, record);
        if (ObjectUtils.isEmpty(record.getId())) {
            record.setId(BaseUtil.createUid());
        }
        int count;
        record.setOperateUserId(userInfo.getUserId() + "");
        record.setOperateUserName(userInfo.getRealName());
        if (RecordSaveTypeEnum.ADD.getCode().equals(operateType)) {
            count = casePunishDecisionRevokeRecordMapper.insertSelective(record);
        } else {
            String id = saveDto.getId();
            CasePunishDecisionRevokeRecordVo vo = getCasePunishDecisionRevokeRecordBasicInfo(caseId);
            if (ObjectUtils.isEmpty(vo)) {
                throw new BusinessException("未匹配到撤销记录");
            }
            if (!ObjectUtils.isEmpty(id)) {
                //id+caseId校验
                if (!id.equals(vo.getId())) {
                    throw new BusinessException("未匹配到撤销记录,caseId:" + caseId + ",id:" + id + "");
                }
            } else {
                throw new BusinessException("修改时请指定主键id");
            }
            count = casePunishDecisionRevokeRecordMapper.updateByPrimaryKeySelective(record);
        }
        //保存附件信息
        List<CaseAttachmentInfoSaveDto> revokeRelatedAttachmentList = saveDto.getRevokeRelatedAttachmentList();
        String documentCatalogCode = saveDto.getDocumentCatalogCode();
        caseAppendixRecordService.removeCaseAppendixRecordByCaseIdAndCatalogCode(caseId,documentCatalogCode);
        if(!ObjectUtils.isEmpty(revokeRelatedAttachmentList) &&  revokeRelatedAttachmentList.size()>0){
            revokeRelatedAttachmentList.forEach(e -> {
                CaseAppendixRecord caseAppendixRecord = new CaseAppendixRecord();
                BeanUtils.copyProperties(e, caseAppendixRecord);
                caseAppendixRecord.setId(BaseUtil.createUid());
                caseAppendixRecord.setCaseId(caseId);
                caseAppendixRecord.setCaseStageName(caseMainInfo.getCaseCurrentStageName());
                caseAppendixRecord.setCaseStageCode(caseMainInfo.getCaseCurrentStageCode());
                caseAppendixRecord.setCaseLinkCode(caseMainInfo.getCaseCurrentLinkCode());
                caseAppendixRecord.setCaseLinkName(caseMainInfo.getCaseCurrentLinkName());
                caseAppendixRecord.setDocumentCatalogCode(documentCatalogCode);
                if (!ObjectUtils.isEmpty(userInfo)) {
                    caseAppendixRecord.setUploadUserId(userInfo.getUserId() + "");
                    caseAppendixRecord.setUploadUserName(userInfo.getRealName());
                }
                caseAppendixRecord.setUploadTime(LocalDateTime.now());
                String appendixTypeId = caseAppendixRecord.getAppendixTypeId();
                if (ObjectUtils.isEmpty(appendixTypeId)) {
                    throw new BusinessException("未指定附件类型id【" + caseAppendixRecord.getAppendixName() + "】");
                }
                String appendixUrl = caseAppendixRecord.getAppendixUrl();
                if (ObjectUtils.isEmpty(appendixUrl)) {
                    throw new BusinessException("未指定附件地址【" + caseAppendixRecord.getAppendixName() + "】");
                }
                caseAppendixRecordMapper.insertSelective(caseAppendixRecord);

            });
        }
        log.info("saveCasePunishDecisionRevokeRecordBasicInfo end count:{}", count);
        return count;
    }

    /**
     * 描述：校验撤销基础基本信息
     *
     * @param saveDto {@link CasePunishDecisionRevokeRecordDto}
     * @return String 错误信息
     * @author xiangyuyu
     * @date 2022/7/22
     * @since 1.3.2
     */
    private String validateRevokeBasicInfo(CasePunishDecisionRevokeRecordDto saveDto) {
        String caseId = saveDto.getCaseId();
        if (ObjectUtils.isEmpty(caseId)) {
            return "未指定案件id";
        }

        String revokeReasonCode = saveDto.getRevokeReasonCode();
        if (ObjectUtils.isEmpty(revokeReasonCode)) {
            return "未指定撤销原因编码（数据字典PUNISH_DECISION_REVOKE_REASON）";
        }

        String dealAfterRevokeTypeCode = saveDto.getRevokeReasonCode();
        if (ObjectUtils.isEmpty(dealAfterRevokeTypeCode)) {
            return "未指定撤销后续操作类型编码（数据字典DEAL_AFTER_REVOKE_TYPE）";
        }
        return "";
    }

    /**
     * 【V1.3.2】描述：根据案件id查询案件处罚决定撤销记录基本信息
     *
     * @param caseId 案件id
     * @return {@link CasePunishDecisionRevokeRecordVo}
     * @author xiangyuyu
     * @date 2022/7/22
     * @since 1.3.2
     */
    @Override
    public CasePunishDecisionRevokeRecordVo getCasePunishDecisionRevokeRecordBasicInfo(String caseId) {
        log.info("getCasePunishDecisionRevokeRecordBasicInfo... start(caseId:+" + caseId + ")...");
        Example query = new Example(CasePunishDecisionRevokeRecord.class);
        query.createCriteria().andEqualTo("caseId", caseId).andEqualTo("status",YesOrNoEnum.YES.getCode());
        List<CasePunishDecisionRevokeRecord> list = casePunishDecisionRevokeRecordMapper.selectByExample(query);
        CasePunishDecisionRevokeRecordVo vo = new CasePunishDecisionRevokeRecordVo();
        if (ObjectUtils.isEmpty(list) || list.size() == 0) {
            return vo;
        }
        CasePunishDecisionRevokeRecord record = list.get(Constant.INTEGER_0);
        BeanUtils.copyProperties(record, vo);

        //获取附件信息
        CaseAttachmentInfoQueryDto queryAttach = new CaseAttachmentInfoQueryDto();
        queryAttach.setCaseId(caseId);
        CaseMainInfoVo caseMainInfoVo = caseMainInfoService.getCaseMainInfo(caseId);
        String flowCode = caseMainInfoVo.getCaseFlowCode();
        String versionCode = caseMainInfoVo.getCaseFlowVersion();
        List<ConfigWorkFlowDocument>  configWorkFlowDocuments = configWorkFlowDocumentService.getConfigWorkFlowDocumentListByLinkCode(flowCode,caseMainInfoVo.getCaseCurrentLinkCode(),versionCode, DocumentTypeEnum.APPROVAL_TABLE.getCode());
        String documentCatalogCode = null;
        for (ConfigWorkFlowDocument e : configWorkFlowDocuments) {
            if(Constant.STRING_KIND_CODE_XZCFCXSPB.equals(e.getDocumentKindCode())){
                documentCatalogCode = e.getDocumentCatalogCode();
                break;
            }
        }
        //获取文书目录编码
        if(!ObjectUtils.isEmpty(documentCatalogCode)){
            queryAttach.setCaseId(caseId);
            queryAttach.setDocumentCatalogCode(documentCatalogCode);
            //获取附件信息
            List<CaseAttachmentInfoVo> attachmentList = caseAppendixRecordService.getCaseAttachmentInfoList(queryAttach);
            vo.setRevokeRelatedAttachmentList(attachmentList);
        } else {
            log.warn("未匹配到工作流文书配置信息");
            return null;
        }
        log.info("getCasePunishDecisionRevokeRecordBasicInfo end-vo:" + vo);
        return vo;
    }

    /**
     * 描述：处罚决定撤销后续处理
     *
     * @param caseId                  案件id
     * @param dealAfterRevokeTypeCode 撤销后续操作类型编码
     * @return String 处理结果
     * @author xiangyuyu
     * @date 2022/7/28
     * @since 1.3.2
     */
    @Override
    public String dealAfterPunishRevoke(String caseId, String dealAfterRevokeTypeCode) {
        //无效决定书缴款状态
        CasePaymentMainRecord casePaymentMainRecord=casePaymentMainRecordService.getCasePaymentMainRecord(caseId);
        if(!ObjectUtils.isEmpty(casePaymentMainRecord)){
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("docNumber",casePaymentMainRecord.getNoticeNo());
            jsonObject.put("deptId",casePaymentMainRecord.getEnterCode());
            HttpUtils.doPostJson(busInvalidUnpayDataUrl, jsonObject.toJSONString());
        }
        //根据不同的撤销后续操作进行不同处理
        if (DealAfterRevokeTypeEnum.CASE_TERMINATE.getCode().equals(dealAfterRevokeTypeCode)) {
            //案件终止
            caseMainInfoStatusChangeRecordService.saveCaseTerminateRecord(caseId, CaseStatusEnum.PUNISH_REVOKE.getCode());
        } else if (DealAfterRevokeTypeEnum.TO_INVESTIGATION.getCode().equals(dealAfterRevokeTypeCode)) {
            //案件撤回调查取证
            //获取调查取证的linkCode编码
            CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
            String flowCode = caseMainInfo.getCaseFlowCode();
            String flowVersion = caseMainInfo.getCaseFlowVersion();

            List<ConfigWorkFlowDetailInfo> configFlowList = configWorkFlowDetailInfoService.getConfigWorkFlowDetailInfoByWorkFlowInfo(flowCode,flowVersion);
            String investigationCode = null;
            List<ConfigWorkFlowDetailInfo> sortConfigFlowList=configFlowList.stream().sorted(Comparator.comparing(ConfigWorkFlowDetailInfo::getWorkLinkCode)).collect(Collectors.toList());
            for (ConfigWorkFlowDetailInfo e : sortConfigFlowList) {
                if("INVESTIGATION".equals(e.getWorkStageCode())){
                    investigationCode = e.getWorkLinkCode();
                    break;
                }
            }
            configWorkFlowDocumentService.getConfigWorkFlowDocumentMatchedListByFlowCode(flowCode,flowVersion);
            if(ObjectUtils.isEmpty(investigationCode)){
                throw new BusinessException("未找到当前工作流对应调查取证环节配置信息，flowCode："+flowCode+"，flowVersion："+flowVersion);
            }
            caseMainInfoService.doRecallCaseHandleLink(caseId, investigationCode);
            //更新案件状态为办案中
            CaseMainInfo caseInfo=caseMainInfoMapper.selectByPrimaryKey(caseId);
            caseInfo.setCaseStatus(CaseStatusEnum.HANDLING_CASE.getCode());
            caseInfo.setCaseVerdictEndTime(null);
            caseMainInfoMapper.updateByPrimaryKey(caseInfo);
            //如果撤销到调查取证，生成一条处罚决定撤销记录，然后定时上报删除案件当前阶段以及后面阶段已经上报成功的数据
            String userId = "";
            UserDTO userInfo = UserUtil.getUserInfo();
            if(userInfo != null){
                userId = String.valueOf(userInfo.getUserId());
            }
            caseDataChangeReportRecordService.save(caseId, CaseChangeOperationTypeEnum.OPERATION_TYPE_7.getCode(), userId);
        }
        //更新案件处罚决定撤销记录状态为无效
        CasePunishDecisionRevokeRecord record = new CasePunishDecisionRevokeRecord();
        Example update = new Example(CasePunishDecisionRevokeRecord.class);
        update.createCriteria().andEqualTo("caseId", caseId);
        record.setStatus(YesOrNoEnum.NO.getCode());
        casePunishDecisionRevokeRecordMapper.updateByExampleSelective(record, update);

        CasePartiesRecordQueryDto queryDto = new CasePartiesRecordQueryDto();
        queryDto.setCaseId(caseId);
        //获取当事人信息
        List<CasePartiesInfoVo> partyInfo = casePartiesRecordService.getCasePartiesInfoList(queryDto);
        // FIXME: 2022/8/4 目前只支持单当事人
        String partyId = partyInfo.get(Constant.INTEGER_0).getPartyId();
        //撤销公示
        // FIXME: 2022/8/4 撤销原因没有可视化录入的入口，暂时写死"-"
        RevokeDecisionOrCaseInfoDto dto = new RevokeDecisionOrCaseInfoDto(caseId,null,Constant.STRING_2,Constant.STRING_HORIZONTAL_BARS,partyId);
        caseDataReportDecisionService.revokeDecisionOrCaseInfo(dto);
        return "";
    }
}